package com.yf.dxapp.module.app.controller.app;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.JakartaServletUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.security.config.SecurityProperties;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi;
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
import com.yf.dxapp.module.app.component.app.QiniuFileComponent;
import com.yf.dxapp.module.app.controller.admin.appuser.vo.AppUserSaveReqVO;
import com.yf.dxapp.module.app.controller.app.vo.*;
import com.yf.dxapp.module.app.filter.AppLoginFilter;
import com.yf.dxapp.module.app.service.appuser.AppUserService;
import com.yf.dxapp.module.app.service.login.LoginService;
import com.yf.dxapp.module.app.sms.SmsService;
import jakarta.annotation.Resource;
import jakarta.annotation.security.PermitAll;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Optional;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;


@Slf4j
@RestController
public class ApiAppLoginController {

    @Resource
    private LoginService loginService;

    @Resource
    private SmsService smsService;

    @Resource
    private AppUserService appUserService;

    @Resource
    private QiniuFileComponent qiniuFileComponent;

    @Resource
    private SecurityProperties securityProperties;

    @Resource
    private OAuth2TokenApi oauth2TokenApi;

    @RequestMapping("/captcha")
    @PermitAll
    public CommonResult captcha(@RequestBody SmsCodeSendReqDTO req) {
        if (StringUtils.isBlank(req.getMobile())) {
            return error(-1, "请输入手机号");
        }
        smsService.sendCaptcha(req.getMobile());
        return success(9999);
    }


    /**
     * 手机号验证码登录
     *
     * @return
     */
    @PostMapping("/phone")
    @PermitAll
    public CommonResult phoneLogin(@RequestBody PhoneLoginDTO phoneLoginDTO) {
        phoneLoginDTO.setUsedIp(getClientIP());
        PhoneLoginVO phoneLoginVO = loginService.phoneLogin(phoneLoginDTO);
        return success(phoneLoginVO);
    }

    /**
     * 账号密码登录
     *
     * @return
     */
    @PostMapping("/code")
    @PermitAll
    public CommonResult codeLogin(@RequestBody CodeLoginDTO codeLoginDTO) {
        CodeLoginVO codeLoginVO = loginService.codeLogin(codeLoginDTO);
        return success(codeLoginVO);
    }

    /**
     * 退出登录
     *
     * @return
     */
    @PostMapping("/user/logout")
    public CommonResult logout(HttpServletRequest request) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        boolean result = loginService.logout(userId);
        log.info("用户{}操作登出账户，登出结果:{}", userId, result);
        String token = SecurityFrameworkUtils.obtainAuthorization(request,
                AppLoginFilter.YF_TOKEN, securityProperties.getTokenParameter());
        if (StrUtil.isNotBlank(token)) {
            oauth2TokenApi.removeAccessToken(token);
        }
        return success(result);
    }

    @PostMapping("/user/update")
    public CommonResult update(@RequestBody @Validated AppUserSaveReqVO req) {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        req.setId(loginUserId);
        if (Optional.ofNullable(req.getNeedDomain()).orElse(false)) {
            req.setAvatar(qiniuFileComponent.complementImgUrl(req.getAvatar()));
        }
        appUserService.updateAppUser(req);
        return success(true);
    }

    /**
     * 注销账户
     *
     * @return
     */
    @PostMapping("/user/signoff")
    private CommonResult signOff(HttpServletRequest request, @RequestBody SignOffVo signOffVo) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        boolean logout = loginService.logout(userId);
        String token = SecurityFrameworkUtils.obtainAuthorization(request,
                AppLoginFilter.YF_TOKEN, securityProperties.getTokenParameter());
        if (StrUtil.isNotBlank(token)) {
            oauth2TokenApi.removeAccessToken(token);
        }
        if (logout) {
            boolean result = appUserService.signOff(userId, signOffVo != null ? signOffVo.getReason() : "");
            return success(result);
        }
        return success(false);
    }

    private static String getClientIP() {
        HttpServletRequest request = getRequest();
        if (request == null) {
            return null;
        }
        return JakartaServletUtil.getClientIP(request);
    }

    /**
     * 获得请求
     *
     * @return HttpServletRequest
     */
    private static HttpServletRequest getRequest() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (!(requestAttributes instanceof ServletRequestAttributes)) {
            return null;
        }
        return ((ServletRequestAttributes) requestAttributes).getRequest();
    }
}
